#include "stdafx.h"
#include <QStringList>

static const QRectF size = QRectF(-20, -20, 40, 40);
static const int selection_width = 7;

Node::Node(SceneView *_scene, QString _name, QPointF _pos)
	: scene(_scene)
{
	setFlag(ItemIsMovable);
	setFlag(ItemIsSelectable);
	setFlag(ItemSendsGeometryChanges);
	setCacheMode(DeviceCoordinateCache);
	type = BLANK;
	if (_name == "") _name = getDefaultName();
	title = new Title(this, _name, QPointF(18, -20));
	this->setPos(_pos);
	title->adjust();
	scene->addItem(this);
	scene->addItem(title);
	init_model();
	accepted = false;
}

Node::Node(SceneView *_scene): scene(_scene){
	type = BLANK;
}

Node::~Node(){
	scene->node_list.erase(find(scene->node_list.begin(), scene->node_list.end(), this));
	foreach(PipeLine *p, inletList)
		delete p;
	foreach(PipeLine *p, outletList)
		delete p;
	delete title;
	delete model;
}

QString Node::getDefaultName(){
	QString text;
	int num = 0;
	bool findNum = true;
	while (findNum){
		findNum = false;
		num++;
		text = "node " + QString::number(num);
		foreach (Node *node, scene->node_list)
			if (node->title->title() == text){
				findNum = true;
				break;
			}
	}	
	return text;
}

QRectF Node::boundingRect() const{
	return size.normalized().adjusted(-selection_width, -selection_width, selection_width, selection_width);
}

void Node::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *){
	
	painter->setRenderHint(QPainter::Antialiasing);
	if (isSelected()){
		painter->setPen(Qt::NoPen);
		painter->setBrush(QColor(0, 162, 232, 100));
		painter->drawEllipse(size.normalized().adjusted(-selection_width, -selection_width, selection_width, selection_width));
	}

	QColor backColor;
	QString caption;
	painter->setPen(Qt::black);
	QFont font;
	font.setPointSize(14);
	
	painter->setFont(font);
	switch (type){
	case INLET:
		caption = "In";
		backColor.setRgb(167, 211, 92);
		break;
	case OUTLET:
		caption = "Out";
		backColor.setRgb(126, 211, 214);
		break;
	case SPLITTER:
		caption = "";
		backColor.setRgb(200, 200, 200);
		break;
	case BLANK:
		caption = "";
		backColor.setRgb(235, 197, 65);
		break;
	default:
		caption = "err";
		backColor.setRgb(243, 145, 63);
	}

	if (!accepted) painter->setPen(QPen(Qt::darkGray, 3));
	else painter->setPen(QPen(QColor(21, 147, 55), 4));

	painter->setBrush(backColor);
	/*if (type == SPLITTER){
		painter->drawEllipse(size.normalized().adjusted(8, 8, -8, -8));
	}else{*/
	painter->drawEllipse(size);
	//}
	
	painter->setPen(QPen(QColor(100, 100, 100)));
	painter->drawText(size, Qt::AlignCenter, caption);

}

QVariant Node::itemChange(GraphicsItemChange change, const QVariant &value){
	if(change == ItemPositionHasChanged){
		foreach(PipeLine *p, inletList) p->adjust();
		foreach(PipeLine *p, outletList) p->adjust();
		title->adjust();
	}
	if(change == ItemSelectedHasChanged){
		if (isSelected()){
			scene->main->setPropertiesModel(model);
		}
	}
	return QGraphicsItem::itemChange(change, value);
}

void Node::mousePressEvent(QGraphicsSceneMouseEvent *event){
	update();
	QGraphicsItem::mousePressEvent(event);
}

void Node::mouseReleaseEvent(QGraphicsSceneMouseEvent *event){
	emit setModelData(1, 0, pos().x());
	emit setModelData(1, 1, pos().y());
	emit setModelData(-1, 1, QString::number(pos().x()) + "; " + QString::number(pos().y()));
	update();
	QGraphicsItem::mouseReleaseEvent(event);
}

void Node::mouseMoveEvent(QGraphicsSceneMouseEvent *event){
	update();
	QGraphicsItem::mouseMoveEvent(event);
}

void Node::addOutletPipe(PipeLine *pipeline){
	outletList << pipeline;
	type = getType();
	emit setModelData(-1, 2, getStringType());
	update();
}

void Node::addInletPipe(PipeLine *pipeline){
	inletList << pipeline;
	type = getType();
	emit setModelData(-1, 2, getStringType());
	update();
}

void Node::removeInletPipe(PipeLine *pipeline){
	inletList.erase(find(inletList.begin(), inletList.end(), pipeline));
	type = getType();
	emit setModelData(-1, 2, getStringType());
	update();
}

void Node::removeOutletPipe(PipeLine *pipeline){
	outletList.erase(find(outletList.begin(), outletList.end(), pipeline));
	type = getType();
	emit setModelData(-1, 2, getStringType());
	update();
}

NodeType_t Node::getType(){
	NodeType_t t;
	if (inletList.size()){
		if (outletList.size()) t = SPLITTER;
		else t = INLET;
	}else{
		if (outletList.size()) t = OUTLET;
		else t = BLANK;
	}
	return t;
}

void Node::init_model(){
	//0 - boolean
	//1 - spinbox
	//2 - textbox
	//3 - label
	//4 - combobox
	//5 - button
	model = new PropertiesModel(this);
	model->addItem("NAME", title->title(), "", 2, 0,"name must be unique.");
	model->addItem("LOCATION", QString::number(pos().x()) + "; " + QString::number(pos().y()), "px", 3, 0, "location on scene", false, true);
	model->addItem("X", pos().x(), "px", 1, 0, "X position", "", true);
	model->addItem("Y", pos().y(), "px", 1, 0, "Y position", "", true);
	model->addItem("TYPE", "BLANK", "", 3, 0, "node type");
	model->addItem("DISPLAY TITLE", title->isVisible(), "", 0, 0, "Use to show/hide title");
	//model->addItem("OIL MODEL", OilModelListChanged(), "", 4, 0);
	model->addItem("PRESSURE", "both:piecewise-constant/time,pressure/s,Pa/", "edit", 5, 0);
	connect(this, SIGNAL(setModelData(const int &, const int &, const QVariant &)), 
		model, SLOT(changeData(const int &, const int &, const QVariant &)));

	connect(model, SIGNAL(ItemChanged(const int &, const int &, const QVariant &)),
		this, SLOT(getModelData(const int &, const int &, const QVariant &)));

	connect(model, SIGNAL(update()), this, SLOT(updateProperties()));

	connect(scene->main, SIGNAL(OilModelListChanged(QString)), this, SLOT(OilModelListChanged(QString)));
}


void Node::getModelData(const int &parent_row, const int &row, const QVariant &value){
	if (parent_row == -1 && row == 0){
		title->setTitle(value.toString());
		return;
	}
	if (parent_row == 1 && row == 0){
		setX(value.toInt());
		return;
	}
	if (parent_row == 1 && row == 1){
		setY(value.toInt());
		return;
	}
	if (parent_row == -1 && row == 3){
		title->setVisible(value.toBool());
		return;
	}
	/*if (parent_row == -1 && row == 4){
		OilModelList = value.toString();
		return;
	}*/
}

void Node::updateProperties(){
	scene->main->properties->setItemDelegate(new Delegate(scene->main));
}

QString Node::getStringType(){
	QString tp;
	switch (type){
	case 0:
		tp = "INLET";
		break;
	case 1:
		tp = "OUTLET";
		break;
	case 2:
		tp = "SPLITTER";
		break;
	default:
		tp = "BLANK";
	}
	return tp;
}

/*
QString Node::OilModelListChanged(QString list){
	QStringList old_list = OilModelList.split(";");
	QStringList cur_list = list.split(";");
	QString str;

	int i = 0;
	if(list != ""){
		QString cur_oil_model = old_list[old_list[0].toInt() + 1];
		for (i = 1; i < cur_list.count() + 1; i++)
			if (cur_oil_model == cur_list[i - 1])
				break;
		
	}
	if (i == cur_list.count() + 1) i = 0;
	str = QString::number(i) + ";NONE";
	for (int i = 0; i < cur_list.count(); i++)
		if(cur_list[i] != "")
			str += ";" + cur_list[i];
	OilModelList = str;
	emit setModelData(-1, 4, str);
	return str;
}*/